-- SPDX-License-Identifier: GPL-3.0-or-later

-- hs_ex.lua对标FreeKill的fk_ex.lua
-- 目的是提供类似FreeKill拓展般的炉石传说酒馆战棋拓展语法
-- 让作者能方便地创建随从、法术、武器等卡牌

-- 首先加载所有卡牌类型
CardItem = require "packages.hearthstone.battlegrounds.core.card.carditem"
Minion = require "packages.hearthstone.battlegrounds.core.card.minion"
Spell = require "packages.hearthstone.battlegrounds.core.card.spell"
--Weapon = require "packages.hearthstone.battlegrounds.core.card.weapon"

-- 全局表，用于存储创建的卡牌
hs = hs or {}

--全局卡牌表
hs.cards = hs.cards or {}

---@class BaseCardSpec
---@field public name string @ 卡牌名称
---@field public cost integer @ 法力值消耗
---@field public rarity string @ 稀有度："common" | "rare" | "epic" | "legendary"
---@field public card_class string @ 职业："neutral" | "warrior" | "mage" 等
---@field public card_set string @ 卡牌集："basic" | "classic" | "battlegrounds" 等
---@field public collectible boolean? @ 是否可收集，默认true
---@field public skills string[]? @ 技能名称列表
---@field public description string? @ 卡牌描述

---@class MinionSpec : BaseCardSpec
---@field public atk integer @ 攻击力
---@field public hp integer @ 生命值
---@field public race string? @ 种族："beast" | "demon" | "mech" 等，默认"none"
---@field public tags string[]? @ 特殊标签："taunt" | "divine_shield" | "poisonous" 等
---@field public tavern_level integer? @ 酒馆等级(1-6)，仅酒馆战旗模式使用
---@field public tavern_tier integer? @ 酒馆品质（金色=3星），仅酒馆战旗模式使用
---@field public battlecry function? @ 战吼效果函数
---@field public deathrattle function? @ 亡语效果函数
---@field public aura function? @ 光环效果函数
---@field public on_attack function? @ 攻击时效果函数
---@field public on_damage function? @ 受到伤害时效果函数
---@field public on_heal function? @ 治疗时效果函数

---@class SpellSpec : BaseCardSpec
---@field public spell_school string? @ 法术学派："arcane" | "fire" | "frost" 等，默认"none"
---@field public target_type string? @ 目标类型："character" | "minion" | "none"，默认"none"
---@field public tavern_level integer? @ 酒馆等级，仅酒馆战旗模式使用
---@field public effect function @ 法术效果函数
---@field public can_cast function? @ 判断是否可以施法的函数

---@class WeaponSpec : BaseCardSpec
---@field public atk integer @ 攻击力
---@field public durability integer @ 耐久度
---@field public on_equip function? @ 装备时效果函数
---@field public on_attack function? @ 攻击时效果函数
---@field public on_destroy function? @ 摧毁时效果函数

---@class HeroSpec : BaseCardSpec
---@field public armor integer? @ 护甲值
---@field public hero_power string? @ 英雄技能名称
---@field public on_hero_power function? @ 英雄技能效果函数

-- 通用卡牌规格处理函数
function hs.readCommonSpecToCard(card, spec)
  -- 验证必需字段
  assert(type(spec.name) == "string", "Card name must be a string")
  assert(type(spec.cost) == "number", "Card cost must be a number")
  
  -- 设置基本属性
  card.name = spec.name
  card.cost = spec.cost
  card.rarity = spec.rarity or CardItem.Common
  card.card_class = spec.card_class or CardItem.Neutral
  card.card_set = spec.card_set or CardItem.SetBattlegrounds
  card.collectible = spec.collectible ~= false -- 默认可收集
  
  -- 添加技能
  if spec.skills then
    for _, skill_name in ipairs(spec.skills) do
      local skill = Fk.skills[skill_name]
      if skill then
        card:addSkill(skill)
      else
        fk.qWarning(string.format("Skill '%s' not found for card '%s'", skill_name, spec.name))
      end
    end
  end
  
  -- 设置描述
  if spec.description then
    -- 这里可以设置多语言描述
    Fk:translate(":" .. spec.name, "zh_CN", spec.description)
  end
end

-- 随从规格处理函数
function hs.readMinionSpecToCard(minion, spec)
  hs.readCommonSpecToCard(minion, spec)
  
  -- 验证随从必需字段
  assert(type(spec.atk) == "number", "Minion attack must be a number")
  assert(type(spec.hp) == "number", "Minion health must be a number")
  
  -- 设置随从属性
  minion.atk = spec.atk
  minion.hp = spec.hp
  minion.maxHp = spec.hp
  minion.race = spec.race or Minion.None
  minion.tags = spec.tags or {}
  minion.tavern_level = spec.tavern_level
  minion.tavern_tier = spec.tavern_tier
  
  -- 设置效果函数
  if spec.battlecry then
    minion.battlecry = spec.battlecry
  end
  if spec.deathrattle then
    minion.deathrattle = spec.deathrattle
  end
  if spec.aura then
    minion.aura = spec.aura
  end
  if spec.on_attack then
    minion.on_attack = spec.on_attack
  end
  if spec.on_damage then
    minion.on_damage = spec.on_damage
  end
  if spec.on_heal then
    minion.on_heal = spec.on_heal
  end
end

-- 法术规格处理函数
function hs.readSpellSpecToCard(spell, spec)
  hs.readCommonSpecToCard(spell, spec)
  
  -- 验证法术必需字段
  assert(type(spec.effect) == "function", "Spell effect must be a function")
  
  -- 设置法术属性
  spell.spell_school = spec.spell_school or Spell.None
  spell.target_type = spec.target_type or Spell.TargetNone
  spell.tavern_level = spec.tavern_level
  spell.effect = spec.effect
  
  if spec.can_cast then
    spell.can_cast = spec.can_cast
  end
end

-- 武器规格处理函数
function hs.readWeaponSpecToCard(weapon, spec)
  hs.readCommonSpecToCard(weapon, spec)
  
  -- 验证武器必需字段
  assert(type(spec.atk) == "number", "Weapon attack must be a number")
  assert(type(spec.durability) == "number", "Weapon durability must be a number")
  
  -- 设置武器属性
  weapon.atk = spec.atk
  weapon.durability = spec.durability
  weapon.maxDurability = spec.durability
  
  -- 设置效果函数
  if spec.on_equip then
    weapon.on_equip = spec.on_equip
  end
  if spec.on_attack then
    weapon.on_attack = spec.on_attack
  end
  if spec.on_destroy then
    weapon.on_destroy = spec.on_destroy
  end
end
local cardId = 1
---创建随从
---@param spec MinionSpec @ 随从规格
---@return Minion
function hs.CreateMinion(spec)
  local minion = Minion:new(
    spec.name,
    spec.cost,
    spec.atk,
    spec.hp,
    spec.race,
    spec.rarity,
    spec.card_class,
    spec.card_set,
    spec.tavern_level
  )
  minion.id = cardId
  cardId = cardId + 1
  hs.readMinionSpecToCard(minion, spec)
  
  -- 注册到全局卡牌表
  hs.cards[spec.name] = minion
  
  return minion
end

---创建法术
---@param spec SpellSpec @ 法术规格
---@return Spell
function hs.CreateSpell(spec)
  local spell = Spell:new(
    spec.name,
    spec.cost,
    spec.spell_school,
    spec.target_type,
    spec.rarity,
    spec.card_class,
    spec.card_set,
    spec.tavern_level
  )
  
  hs.readSpellSpecToCard(spell, spec)
  
  -- 注册到全局卡牌表
  hs.cards[spec.name] = spell
  
  return spell
end

---创建武器
---@param spec WeaponSpec @ 武器规格
---@return Weapon
function hs.CreateWeapon(spec)
  local weapon = Weapon:new(
    spec.name,
    spec.cost,
    spec.atk,
    spec.durability,
    spec.rarity,
    spec.card_class,
    spec.card_set
  )
  
  hs.readWeaponSpecToCard(weapon, spec)
  
  -- 注册到全局卡牌表
  hs.cards[spec.name] = weapon
  
  return weapon
end

---创建英雄（扩展功能）
---@param spec HeroSpec @ 英雄规格
---@return CardItem
function hs.CreateHero(spec)
  local hero = CardItem:new(
    spec.name,
    spec.cost,
    CardItem.TypeHero,
    spec.rarity,
    spec.card_class,
    spec.card_set,
    spec.collectible
  )
  
  hs.readCommonSpecToCard(hero, spec)
  
  -- 设置英雄特有属性
  hero.armor = spec.armor or 0
  
  if spec.hero_power then
    local hero_power_skill = Fk.skills[spec.hero_power]
    if hero_power_skill then
      hero:addSkill(hero_power_skill)
    end
  end
  
  if spec.on_hero_power then
    hero.on_hero_power = spec.on_hero_power
  end
  
  -- 注册到全局卡牌表
  hs.cards[spec.name] = hero
  
  return hero
end

-- 便捷函数：批量创建随从
---@param specs MinionSpec[] @ 随从规格列表
---@return Minion[]
function hs.CreateMinions(specs)
  local minions = {}
  for _, spec in ipairs(specs) do
    table.insert(minions, hs.CreateMinion(spec))
  end
  return minions
end

-- 便捷函数：批量创建法术
---@param specs SpellSpec[] @ 法术规格列表
---@return Spell[]
function hs.CreateSpells(specs)
  local spells = {}
  for _, spec in ipairs(specs) do
    table.insert(spells, hs.CreateSpell(spec))
  end
  return spells
end

-- 便捷函数：批量创建武器
---@param specs WeaponSpec[] @ 武器规格列表
---@return Weapon[]
function hs.CreateWeapons(specs)
  local weapons = {}
  for _, spec in ipairs(specs) do
    table.insert(weapons, hs.CreateWeapon(spec))
  end
  return weapons
end

-- 便捷函数：获取已创建的卡牌
---@param name string @ 卡牌名称
---@return CardItem?
function hs.GetCard(name)
  return hs.cards[name]
end

-- 便捷函数：获取所有已创建的卡牌
---@return table<string, CardItem>
function hs.GetAllCards()
  return hs.cards
end

-- 便捷函数：按类型筛选卡牌
---@param card_type string @ 卡牌类型
---@return CardItem[]
function hs.GetCardsByType(card_type)
  local result = {}
  for _, card in pairs(hs.cards) do
    if card:isType(card_type) then
      table.insert(result, card)
    end
  end
  return result
end

-- 便捷函数：按职业筛选卡牌
---@param card_class string @ 职业
---@return CardItem[]
function hs.GetCardsByClass(card_class)
  local result = {}
  for _, card in pairs(hs.cards) do
    if card:isClass(card_class) then
      table.insert(result, card)
    end
  end
  return result
end

-- 便捷函数：按稀有度筛选卡牌
---@param rarity string @ 稀有度
---@return CardItem[]
function hs.GetCardsByRarity(rarity)
  local result = {}
  for _, card in pairs(hs.cards) do
    if card:isRarity(rarity) then
      table.insert(result, card)
    end
  end
  return result
end

-- 便捷函数：按酒馆等级筛选卡牌
---@param tavern_level integer @ 酒馆等级
---@return CardItem[]
function hs.GetCardsByTavernLevel(tavern_level)
  local result = {}
  for _, card in pairs(hs.cards) do
    if card.tavern_level == tavern_level then
      table.insert(result, card)
    end
  end
  return result
end

-- 便捷函数：按种族筛选随从
---@param race string @ 种族
---@return Minion[]
function hs.GetMinionsByRace(race)
  local result = {}
  for _, card in pairs(hs.cards) do
    if card:isInstanceOf(Minion) and card:isRace(race) then
      table.insert(result, card)
    end
  end
  return result
end

-- 便捷函数：按标签筛选随从
---@param tag string @ 标签
---@return Minion[]
function hs.GetMinionsByTag(tag)
  local result = {}
  for _, card in pairs(hs.cards) do
    if card:isInstanceOf(Minion) and card:hasTag(tag) then
      table.insert(result, card)
    end
  end
  return result
end

-- 便捷函数：按法术学派筛选法术
---@param school string @ 法术学派
---@return Spell[]
function hs.GetSpellsBySchool(school)
  local result = {}
  for _, card in pairs(hs.cards) do
    if card:isInstanceOf(Spell) and card:isSchool(school) then
      table.insert(result, card)
    end
  end
  return result
end

return hs
